package sany.iec.service;

import lombok.extern.slf4j.Slf4j;
import org.openmuc.j60870.ASdu;
import org.openmuc.j60870.ASduType;
import org.openmuc.j60870.CauseOfTransmission;
import org.openmuc.j60870.Connection;
import org.openmuc.j60870.ie.*;
import org.springframework.stereotype.Service;
import sany.iec.entity.IECData;

import java.io.IOException;

/**
 * @Author : 托马斯
 * @Date : 2025/7/2 11:42
 * @Description :
 */
@Service
@Slf4j
public class IecSendMessage {

    /**
     * 广播遥测数据
     */
    public void broadcastAnalogValues(IecServerService emsServerService, IECData iecData) {
        if (!iecData.getType().equals("yc")) {
            log.info("数据不属于遥测，不执行发送指令。IECData: {}", iecData);
            return;
        }
        InformationObject io = new InformationObject(
                iecData.getIOA(),
                new InformationElement[][]{
                        {
                                new IeShortFloat(Float.parseFloat(iecData.getValue().toString())),
                                new IeQuality(false, false, false, false, false)
                        }
                }
        );

        // M_ME_NB_1(普通遥测)：只能传输整数，服务端与客户端需要配合系数 + 偏移进行原始数据的还原。
        // M_ME_TB_1(时标遥测)：只能传输整数，服务端与客户端需要配合系数 + 偏移进行原始数据的还原。（每次发送的数据带有时间）
        // M_ME_NC_1(普通高精度遥测)：直接传输浮点数。
        // M_ME_TC_1(普通高精度带时标遥测)：直接传输浮点数。
        ASdu aSdu = new ASdu(ASduType.M_ME_NC_1, false, CauseOfTransmission.SPONTANEOUS,
                false, false, 0, iecData.getCOA(), new InformationObject[]{io});

        sendToAllConnections(emsServerService, aSdu);
    }

    /**
     * 广播遥信数据
     */
    public void broadcastStatusValues(IecServerService emsServerService, IECData iecData) {
        if (!iecData.getType().equals("yx")) {
            log.info("数据不属于遥信，不执行发送指令。IECData: {}", iecData);
            return;
        }
        InformationObject ios = new InformationObject(
                iecData.getIOA(), // 正确写入每个遥信点的 IOA
                new IeSinglePointWithQuality(
                        Float.parseFloat(iecData.getValue().toString()) == 1.0,  // 遥信状态 true/false
                        false, false, false, false // 质量位：无故障
                )
        );

        ASdu aSdu = new ASdu(ASduType.M_SP_NA_1, false, CauseOfTransmission.SPONTANEOUS,
                false, false, 0, 1, ios);

        sendToAllConnections(emsServerService, aSdu);
    }

    /**
     * 向所有活跃连接发送ASDU
     */
    private void sendToAllConnections(IecServerService emsServerService, ASdu aSdu) {
        for (Connection conn : emsServerService.getConnections()) {
            try {
                if (!conn.isClosed()) {
                    conn.send(aSdu);
                    log.debug("已发送数据至客户端: {}", conn.getLocalAddress());
                } else {
                    log.info("清理无效链接！！！");
                    emsServerService.removeConnection(conn); // 清理无效连接
                }
            } catch (IOException e) {
                log.error("发送数据失败: {}", conn.getLocalAddress(), e);
                emsServerService.removeConnection(conn);
            }
        }
    }

}
